2bb8434e3054ceaecfd50515f40a3ce1608c73c4,src/net/spfbl/spf/SPF.java,SPF,processSPF,#String#String#,3679
Before Change
return "FAIL\n";
} else if (sender != null && !Domain.isEmail(sender)) {
String ticket = SPF.addQuery(tokenSet);
CacheComplain.addComplain(client, ticket);
return "INVALID\n";
} else if (sender != null && Domain.isReserved(sender)) {
String ticket = SPF.addQuery(tokenSet);
CacheComplain.addComplain(client, ticket);
return "INVALID\n";
} else if (sender == null && !CacheHELO.match(ip, hostname)) {
String ticket = SPF.addQuery(tokenSet);
CacheComplain.addComplain(client, ticket);
// HELO inválido sem remetente.
return "INVALID\n";
} else if (hostname == null && Core.isReverseRequired()) {
String ticket = SPF.addQuery(tokenSet);
CacheComplain.addComplain(client, ticket);
if (Block.tryAdd(ip)) {
Server.logDebug("new BLOCK '" + ip + "' added by 'ReverseRequired'.");
}
// Require a valid HELO or reverse.
return "INVALID\n";
} else if (Trap.contains(client, recipient)) {
// Calcula frequencia de consultas.
String ticket = SPF.addQuery(tokenSet);
CacheComplain.addComplain(client, ticket);
return "SPAMTRAP\n";
} else if (Defer.count(fluxo) > Core.getFloodMaxRetry()) {
// A origem atingiu o limite de atraso
After Change
return "ERROR: QUERY\n";
} else {
String origin;
if (client == null) {
origin = ipAddress.getHostAddress();
} else if (client.hasEmail()) {
origin = ipAddress.getHostAddress() + " " + client.getDomain() + " " + client.getEmail();
} else {
origin = ipAddress.getHostAddress() + " " + client.getDomain();
}
StringTokenizer tokenizer = new StringTokenizer(query, " ");
String firstToken = tokenizer.nextToken();
if (firstToken.equals("SPAM") && tokenizer.countTokens() == 1) {
String ticket = tokenizer.nextToken();
TreeSet<String> tokenSet = CacheComplain.addComplain(origin, ticket);
if (tokenSet == null) {
result = "DUPLICATE COMPLAIN\n";
} else {
String recipient = SPF.getRecipient(ticket);
result = "OK " + tokenSet + (recipient == null ? "" : " >" + recipient) + "\n";
}
} else if (firstToken.equals("HAM") && tokenizer.countTokens() == 1) {
String ticket = tokenizer.nextToken();
TreeSet<String> tokenSet = CacheComplain.deleteComplain(origin, ticket);
if (tokenSet == null) {
result = "ALREADY REMOVED\n";
} else {
String recipient = SPF.getRecipient(ticket);
result = "OK " + tokenSet + (recipient == null ? "" : " >" + recipient) + "\n";
}
} else if (firstToken.equals("REFRESH") && tokenizer.countTokens() == 1) {
String address = tokenizer.nextToken();
try {
if (CacheSPF.refresh(address, true)) {
result = "UPDATED\n";
} else {
result = "NOT LOADED\n";
}
} catch (ProcessException ex) {
result = ex.getMessage() + "\n";
}
} else if ((firstToken.equals("SPF") && tokenizer.countTokens() >= 4)
|| tokenizer.countTokens() == 2 || tokenizer.countTokens() == 1
|| (firstToken.equals("CHECK") && tokenizer.countTokens() == 4)
|| (firstToken.equals("CHECK") && tokenizer.countTokens() == 3)
|| (firstToken.equals("CHECK") && tokenizer.countTokens() == 2)) {
try {
String ip;
String sender;
String helo;
String recipient;
String origem;
String fluxo;
if (firstToken.equals("SPF")) {
// Nova formatação de consulta.
ip = tokenizer.nextToken();
sender = tokenizer.nextToken();
while (!sender.endsWith("'") && tokenizer.hasMoreTokens()) {
sender += " " + tokenizer.nextToken();
}
helo = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : "''";
recipient = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : "''";
ip = ip.substring(1, ip.length() - 1);
sender = sender.substring(1, sender.length() - 1);
helo = helo.substring(1, helo.length() - 1);
recipient = recipient.substring(1, recipient.length() - 1);
if (sender.length() == 0) {
sender = null;
} else {
sender = sender.toLowerCase();
}
if (!Domain.isEmail(recipient)) {
recipient = null;
}
} else if (firstToken.equals("CHECK") && tokenizer.countTokens() == 4) {
ip = tokenizer.nextToken().toLowerCase();
sender = tokenizer.nextToken().toLowerCase();
helo = tokenizer.nextToken().toLowerCase();
recipient = tokenizer.nextToken().toLowerCase();
if (ip.startsWith("'") && ip.endsWith("'")) {
ip = ip.substring(1, ip.length() - 1);
}
if (sender.startsWith("'") && sender.endsWith("'")) {
sender = sender.substring(1, sender.length() - 1);
}
if (helo.startsWith("'") && helo.endsWith("'")) {
helo = helo.substring(1, helo.length() - 1);
}
if (recipient.startsWith("'") && recipient.endsWith("'")) {
recipient = recipient.substring(1, recipient.length() - 1);
}
if (ip.length() == 0) {
ip = null;
}
if (sender.length() == 0) {
sender = null;
}
if (helo.length() == 0) {
helo = null;
}
if (recipient.length() == 0) {
recipient = null;
}
} else {
// Manter compatibilidade da versão antiga.
// Versão obsoleta.
if (firstToken.equals("CHECK")) {
ip = tokenizer.nextToken();
} else {
ip = firstToken;
}
if (tokenizer.countTokens() == 2) {
sender = tokenizer.nextToken().toLowerCase();
helo = tokenizer.nextToken().toLowerCase();
} else {
sender = null;
helo = tokenizer.nextToken().toLowerCase();
}
recipient = null;
if (ip.startsWith("'") && ip.endsWith("'")) {
ip = ip.substring(1, ip.length() - 1);
}
if (sender != null && sender.startsWith("'") && sender.endsWith("'")) {
sender = sender.substring(1, sender.length() - 1);
if (sender.length() == 0) {
sender = null;
}
}
if (helo.startsWith("'") && helo.endsWith("'")) {
helo = helo.substring(1, helo.length() - 1);
}
}
if (!Subnet.isValidIP(ip)) {
return "INVALID\n";
} else if (
Subnet.containsIP("10.0.0.0/8", ip) ||
Subnet.containsIP("172.16.0.0/12", ip) ||
Subnet.containsIP("192.168.0.0/16", ip) ||
Subnet.containsIP("169.254.0.0/16", ip)
) {
// Message from LAN.
return "LAN\n";
} else {
TreeSet<String> tokenSet = new TreeSet<String>();
ip = Subnet.normalizeIP(ip);
tokenSet.add(ip);
if (client != null && client.hasEmail()) {
// Se houver um cliente válido,
// Adicionar no ticket para controle.
tokenSet.add(client.getEmail() + ':');
}
if (Domain.isEmail(recipient)) {
// Se houver um remetente válido,
// Adicionar no ticket para controle.
tokenSet.add('>' + recipient);
} else {
recipient = null;
}
// Passar a acompanhar todos os
// HELO quando apontados para o IP para
// uma nova forma de interpretar dados.
String hostname;
if (CacheHELO.match(ip, helo)) {
helo = Domain.normalizeHostname(helo, true);
hostname = helo;
} else {
hostname = Reverse.getHostname(ip);
hostname = Domain.normalizeHostname(hostname, true);
}
if (hostname == null) {
Server.logDebug("no reverse for " + ip + ".");
} else {
tokenSet.add(hostname);
String ipv4 = CacheHELO.getUniqueIPv4(hostname);
if (ipv4 != null) {
// Equivalência de pilha dupla se
// IPv4 for único para o hostname.
tokenSet.add(ipv4);
}
String ipv6 = CacheHELO.getUniqueIPv6(hostname);
if (ipv6 != null) {
// Equivalência de pilha dupla se
// IPv6 for único para o hostname.
tokenSet.add(ipv6);
}
}
LinkedList<String> logList = null;
if (sender != null && firstToken.equals("CHECK")) {
int index = sender.lastIndexOf('@');
String domain = sender.substring(index + 1);
logList = new LinkedList<String>();
try {
CacheSPF.refresh(domain, false);
} catch (ProcessException ex) {
logList.add("Cannot refresh SPF registry: " + ex.getErrorMessage());
logList.add("Using cached SPF registry.");
}
}
SPF spf;
if (sender == null) {
spf = null;
result = "NONE";
} else if (!Domain.isEmail(sender)) {
spf = null;
result = "NONE";
} else if (Domain.isReserved(sender)) {
spf = null;
result = "NONE";
} else if ((spf = CacheSPF.get(sender)) == null) {
result = "NONE";
} else if (spf.isInexistent()) {
result = "NONE";
} else {
result = spf.getResult(ip, sender, helo, logList);
}
if (result.equals("PASS") || (sender != null && Provider.containsHELO(ip, hostname))) {
// Quando fo PASS, significa que o domínio
// autorizou envio pelo IP, portanto o dono dele
// é responsavel pelas mensagens.
String mx = Domain.extractHost(sender, true);
if (Provider.containsExact(mx)) {
// Listar apenas o remetente se o
// hostname for um provedor de e-mail.
tokenSet.add(sender);
origem = sender;
} else {
// Não é um provedor então
// o MX deve ser listado.
tokenSet.add(mx);
origem = mx;
}
fluxo = origem + ">" + recipient;
} else if (hostname == null) {
origem = (sender == null ? "" : sender + '>') + ip;
fluxo = origem + ">" + recipient;
hostname = helo;
} else {
String dominio = Domain.extractDomain(hostname, true);
origem = (sender == null ? "" : sender + '>') + (dominio == null ? hostname : dominio.substring(1));
fluxo = origem + ">" + recipient;
}
if (firstToken.equals("CHECK")) {
String results = "\nSPF resolution results:\n";
if (logList == null || logList.isEmpty()) {
results += " NONE\n";
} else {
for (String log : logList) {
results += " " + log + "\n";
}
}
String white = White.find(client, ip, sender, hostname, result, recipient);
if (white != null) {
results += "\nFirst WHITE match: " + white + "\n";
}
String block = Block.find(client, ip, sender, hostname, result, recipient);
if (block != null) {
results += "\nFirst BLOCK match: " + block + "\n";
}
results += "\n";
results += "Considered identifiers and status:\n";
tokenSet = expandTokenSet(tokenSet);
TreeMap<String,Distribution> distributionMap = CacheDistribution.getMap(tokenSet);
for (String token : tokenSet) {
if (!token.startsWith(">") && !token.endsWith(":")) {
float probability;
Status status;
if (distributionMap.containsKey(token)) {
Distribution distribution = distributionMap.get(token);
probability = distribution.getSpamProbability(token);
status = distribution.getStatus(token);
} else {
probability = 0.0f;
status = SPF.Status.WHITE;
}
results += " " + token
+ " " + status.name() + " "
+ Server.DECIMAL_FORMAT.format(probability) + "\n";
}
}
results += "\n";
return results;
} else if (White.contains(client, ip, sender, hostname, result, recipient)) {
// if (result.equals("PASS") && White.containsExact(client + ':' + origem + ";PASS>" + recipient)) {
// // Limpa da lista BLOCK um possível falso positivo.
// Block.clear(null, ip, sender, hostname, result, null);
// } else
if (White.contains(client, ip, sender, hostname, result, null)) {
// // Limpa da lista BLOCK um possível falso positivo.
Block.clear(null, ip, sender, hostname, result, null);
}
// Calcula frequencia de consultas.
String url = Core.getSpamURL(recipient);
String ticket = SPF.addQuery(tokenSet);
return result + " " + (url == null ? ticket : url + URLEncoder.encode(ticket, "UTF-8")) + "\n";
} else if (Block.contains(client, ip, sender, hostname, result, recipient)) {
// Calcula frequencia de consultas.
String ticket = SPF.addQuery(tokenSet);
CacheComplain.addComplain(origin, ticket);
String url = Core.getUnblockURL(client, ip, sender, hostname, result, recipient);
if (url == null) {
return "BLOCKED\n";
} else {
return "BLOCKED " + url + "\n";
}
} else if (spf != null && spf.isDefinitelyInexistent()) {
// O domínio foi dado como inexistente inúmeras vezes.
// Rejeitar e denunciar o host pois há abuso de tentativas.
String ticket = SPF.addQuery(tokenSet);
CacheComplain.addComplain(origin, ticket);
return "NXDOMAIN\n";
} else if (spf != null && spf.isInexistent()) {
return "NXDOMAIN\n";
} else if (result.equals("FAIL")) {
String ticket = SPF.addQuery(tokenSet);
CacheComplain.addComplain(origin, ticket);
// Retornar FAIL somente se não houver
// liberação literal do remetente com FAIL.
return "FAIL\n";
} else if (sender != null && !Domain.isEmail(sender)) {
String ticket = SPF.addQuery(tokenSet);
CacheComplain.addComplain(origin, ticket);
return "INVALID\n";
} else if (sender != null && Domain.isReserved(sender)) {
String ticket = SPF.addQuery(tokenSet);
CacheComplain.addComplain(origin, ticket);
return "INVALID\n";
} else if (sender == null && !CacheHELO.match(ip, hostname)) {
String ticket = SPF.addQuery(tokenSet);
CacheComplain.addComplain(origin, ticket);
// HELO inválido sem remetente.
return "INVALID\n";
} else if (hostname == null && Core.isReverseRequired()) {